
package PracticasPL.Practica1_pl;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;


/**
 *
 */
public class App
{	
	Invitacion inv;
	
	App(String file){
	    inv = new Invitacion(file);
	}
	
	class Invitacion
	{
		int index;
		String cad;
		Front front;
		Body body;
		Back back;

		//Constructor
		Invitacion(String file) {
			index = 0;
			cad = file;
			index = cad.indexOf("<invitation>", index) + "<invitation>".length();
			front = new Front(index);
			body = new Body(index);
			back = new Back(index);
		}
		
		public void print(PrintWriter file){
			file.println("<html><head>");
			file.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">");
			file.println("<title> Invitation (sgmlpl/CSS formatting) </title>");
			file.println("<link href=\"http://nereida.deioc.ull.es/%7Epl/perlexamples/invit.css\" rel=\"style-sheet\" type=\"text/css\">");
			file.println("<!-- 24 August 1998 mg -->");
			file.println("</head>");
			file.println("<body>");
			file.println("<h1>INVITATION</h1>");
			front.print(file);
			body.print(file);
			back.print(file);
			file.println("</body></html>");
		}
		
		class Front
		{
			To to;
			Date date;
			Where where;
			Why why = null;

			Front(int i){
				int initInd = cad.indexOf("<front>", i) + "<front>".length();
				to = new To(initInd);
				date = new Date(index);
				where = new Where(index);
				int ind_aux = index;
				why = new Why(index);  //puede no existir
				if (ind_aux == index){ //no existe
					why = null;
				}
				int endInd = cad.indexOf("</front>", index);
				index = endInd + "</front>".length();
			}
			
			public void print(PrintWriter file){
				file.println("<p><table>");
				file.println("<tbody>");
				file.println("<tr>");
				to.print(file);
				file.println("<\tr>");
				file.println("<tr>");
				date.print(file);
				file.println("<\tr>");
				file.println("<tr>");
				where.print(file);
				file.println("<\tr>");
				if (why != null){
					file.println("<tr>");
					why.print(file);
					file.println("<\tr>");	
				}
				file.println("</tbody>");
				file.println("</table>");
				file.println("</p>");
			}
			
			class To
			{
				String text;
				To(int i){
					int initInd = cad.indexOf("<to>", i) + "<to>".length();
					int endInd = cad.indexOf("</to>", initInd);
					text = cad.substring(initInd, endInd);
					index = endInd + "</to>".length();				
				}
				
				public void print(PrintWriter file){
					file.println("<td class=\"front\">To: </td>");
					file.println("<td>" + text + "</td>");
				}
			}
	
			class Date
			{
				String text;
				Date(int i){
					int initInd = cad.indexOf("<date>", i) + "<date>".length();
					int endInd = cad.indexOf("</date>", initInd);
					text = cad.substring(initInd, endInd);
					index = endInd + "</date>".length();			
				}
				public void print(PrintWriter file){
					file.println("<td class=\"front\">When: </td>");
					file.println("<td>" + text + "</td>");
				}
			}
			
			class Where
			{
				String text;
				Where(int i){
					int initInd = cad.indexOf("<where>", i) + "<where>".length();
					int endInd = cad.indexOf("</where>", initInd);
					text = cad.substring(initInd, endInd);
					index = endInd + "</where>".length();
				}
				public void print(PrintWriter file){
					file.println("<td class=\"front\">Venue: </td>");
					file.println("<td>" + text + "</td>");
				}
			}
			
			class Why
			{
				String text;
				Why(int i){
					int initInd = cad.indexOf("<why>", i);
					if (initInd != -1) {  //encontrado tag
					   initInd = initInd + "<why>".length();
					   int endInd = cad.indexOf("</why>", initInd);
					   text = cad.substring(initInd, endInd);
					   index = endInd + "</why>".length();
					}
				}
				public void print(PrintWriter file){
					file.println("<td class=\"front\">Occasion: </td>");
					file.println("<td>" + text + "</td>");
				}
			}
		}
		
		class Body
		{
			Vector vect;
			Par par;
			
			Body(int i){
				vect = new Vector();
				int initInd = cad.indexOf("<body>", i) + "<body>".length();
				System.out.println( "Encontrado body=" + " a partir de " + initInd );
				index = initInd;
				int ind_aux;
				do {//////////OJOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO 
					ind_aux = index;
					par = new Par(index);
					System.out.println( "Creado un Par = " + par.toString());
					//System.out.println( "Encontrado par=" + par.toString() + " a partir de " + index );
					vect.addElement(par);
				} while (ind_aux != index);
				int endInd = cad.indexOf("</body>", initInd);
				index = endInd + "</body>".length();
			}
			
			public void print(PrintWriter file){
				for (int i=0; i < vect.size(); i++){
					((Par) vect.elementAt(i)).print(file);
				}
			}
			

			class Par
			{
				Vector vect;
				String text;
				Emph emph;
				String data;
				int em_ini = 0;
				int em_end = 0;
				int em_ini_p = 0;
				int em_end_p = 0;
				Par(int i){
					vect = new Vector();
					int initInd = cad.indexOf("<par>", i) + "<par>".length();
					int endInd = cad.indexOf("</par>", initInd);
					if (initInd == endInd) {
						return;  //par sin contenidos
					}
					index = endInd + "</par>".length();
					text = cad.substring(initInd, endInd);
					System.out.println( "Encontrado cad =" + text.toString() + " a partir de " + index );
					do {
						emph = new Emph(em_end);
						if (em_end != em_end_p){ //encontrado emph
							if (em_ini == em_end_p) { //no hay string previo
								vect.addElement(emph);
								System.out.println( "Encontrado emph=" + emph.etext + " a partir de " + em_ini );
							} else {                  //debe de haber cadena previa al emph
								data = text.substring(em_end_p, em_ini);
								vect.addElement(data); //los guardamos en orden
								vect.addElement(emph);
								System.out.println( "Encontrado emph dc=" + emph.etext +" despuesde "+ data+ " a partir de " + em_ini );
							}
						} else {  // emph no encontrado, desde el ultimo al final sera cadena
							data = text.substring(em_end_p, text.length());
							if (data.length() > 0) {
							    vect.addElement(data); //solo se guarda si hay contenido
							    System.out.println( "Encontrado data=" + data + " a partir de " + em_end_p );
							}
                            break;
						}
					    //System.out.println( "Antes de igualar= " + em_ini_p + " em_ini " + em_ini );
					    //System.out.println( "antes de igualar 2 =" + em_end_p + " em_end " + em_end);
						em_ini_p = em_ini;
						em_end_p = em_end;
						//System.out.println( "despues de igualar= " + em_ini_p + " em_ini " + em_ini );
					    //System.out.println( "despues  de igualar 2 =" + em_end_p + " em_end " + em_end);
					} while (true);
				}
				
				public void print(PrintWriter file) {
					file.println("<p>");
					for (int i=0; i < vect.size(); i++){
						file.print(vect.elementAt(i).toString());
					}
					file.println("</p>");
				}

				class Emph
				{
					String etext;
					
					Emph(int i){
						int initInd = text.indexOf("<emph>", i);
						if (initInd != -1){
							em_ini = initInd;
							initInd += "<emph>".length();
						    int endInd = text.indexOf("</emph>", initInd);
						    etext = text.substring(initInd, endInd);
						    em_end = endInd + "</emph>".length();
						}
					}
					public String toString() {
						return("<em>" + etext + "</em>");
					}

				}
			}
		}
		class Back
		{
			Signature sig;
			Back(int i){
				int initInd = cad.indexOf("<back>", i) + "<back>".length();
				sig = new Signature(initInd);
				int endInd = cad.indexOf("</back>", initInd);
				index = endInd + "</back>".length();
				
			}
			
			public void print(PrintWriter file){
				sig.print(file);
			}
			
			class Signature
			{
				String text;
				Signature(int i){
			        //System.out.println( "Signature" + text );
					int initInd = cad.indexOf("<signature>", i) + "<signature>".length();
					int endInd = cad.indexOf("</signature>", initInd);
					text = cad.substring(initInd, endInd);
					index = endInd + "</signature>".length();	
				}
				public void print(PrintWriter file){
					file.println("<p class=\"signature\">" + text + "</p>");
				}
			}
		}
	}
	 /** @param filePath the name of the file to open.
	  *  Not sure if it can accept URLs or just filenames. 
	  *  Path handling could be better, and buffer sizes are hardcoded 
	  **/
	private static String readFileAsString(final String filePath) throws java.io.IOException
	{ 
		StringBuffer fileData = new StringBuffer(1000); 
		BufferedReader reader = new BufferedReader( new FileReader(filePath)); 
		char[] buf = new char[1024]; 
		int numRead=0; 
		while((numRead=reader.read(buf)) != -1){ 
			fileData.append(buf, 0, numRead); 
		}
		reader.close();
		return fileData.toString(); 
	}
	
	public static void main( String[] args ) throws IOException
    {   
		String file = readFileAsString(args[0]);
		System.out.println( "Fichero de entrada =" + file );
		App ap = new App(file);
		
		PrintWriter outputStream = null;
		outputStream = new PrintWriter(new FileWriter(args[1]));
		
		ap.inv.print(outputStream);
		outputStream.close();
		
        //System.out.println( "Hello World!2" );
		
    }
	
}

